<?php

declare (strict_types=1);

namespace app\model;

use app\common\model\AuthRole;
use app\common\model\AuthRoleAccess;
use app\common\model\AuthRule;
use think\facade\Cache;
use think\facade\Db;
use think\Exception;
use app\common\model\Admin;

class Auth
{

    /**
     * 管理员数据
     *
     * @param array $data 登录信息
     *
     * @return Admin
     */
    public function getAdminData(array $data): Admin
    {
        $result = Admin::where('account', $data['account'])->findOrFail();
        // 数据判断
        if (Admin::STATUS_DISABLE == $result->status) {
            throw new Exception('账号已禁用');
        }
        if (!password_verify($data['password'], $result->password)) {
            throw new Exception('账号或密码错误');
        }
        return $result;
    }

    /**
     * @param string $pathInfo 路由信息
     *
     * @return array
     */
    public function getRuleByPathInfo(string $pathInfo): array
    {
        $data = AuthRule::field('id, pid, name, title, icon')
            ->where('name', $pathInfo)
            ->find();
        if (!$data->isEmpty()) {
            return $data->toArray();
        }
        return [];
    }

    /**
     * 获取管理员分配的角色
     *
     * @param int|null $uid 管理员id
     *
     * @return array
     */
    public function getAdminRole(int $uid = null): array
    {
        $data = Db::name('auth_role_access')
            ->alias('ara')
            ->join('auth_role ar', 'ara.group_id = ar.id', 'LEFT')
            ->field('ara.uid, ara.group_id, ar.id, ar.pid, ar.name, ar.rules')
            ->where(
                [
                    'ara.uid' => $uid,
                    'ar.status' => AuthRole::STATUS_ENABLE
                ]
            )
            ->select();
        if (!$data->isEmpty()) {
            return $data->toArray();
        }
        return [];
    }

    /**
     * 获取规则列表和面包屑导航条
     *
     * @param int $uid 管理员id
     * @param array $ruleIds 规则id
     * @param bool $isSuper 是否超级管理员 true=是 false=否
     *
     * @return array
     */
    public function getRuleListAndCrumb(int $uid, array $ruleIds, bool $isSuper)
    {
        $list = Cache::remember(
            'sys:cache:menu:' . $uid,
            function () use ($ruleIds, $isSuper) {
                $data = Db::name('auth_rule')
                    ->field('id, pid, name, title, icon, sort')
                    ->when(
                        !$isSuper,
                        function ($query) use ($ruleIds) {
                            $query->whereIn('id', $ruleIds);
                        }
                    )
                    ->where('is_menu', 1)
                    ->order('pid asc,sort asc,id asc')
                    ->select();
                if ($data->isEmpty()) {
                    return [];
                }
                return $data->toArray();
            }
        );
        $crumb = Cache::remember(
            'sys:cache:crumb:' . $uid,
            function () use ($ruleIds, $isSuper) {
                $data = Db::name('auth_rule')
                    ->field('id, pid, name, title, icon, sort')
                    ->when(
                        !$isSuper,
                        function ($query) use ($ruleIds) {
                            $query->whereIn('id', $ruleIds);
                        }
                    )
                    ->order('pid asc,sort asc,id asc')
                    ->select();
                if ($data->isEmpty()) {
                    return [];
                }
                return $data->toArray();
            }
        );
        return [$list, $crumb];
    }

    /**
     * 获取权限角色数据列表
     *
     * @param array $roleIds 角色数组
     *
     * @return array
     */
    public function getAuthRoleList(array $roleIds): array
    {
        $data = AuthRoleAccess::field('uid, group_id')
            ->whereIn('group_id', $roleIds)
            ->select();
        return $data;
    }

    /**
     * 所有管理者id
     *
     * @return array
     */
    public function getAllAdminId(): array
    {
        return Admin::column('id');
    }

    /**
     * 获取所有角色
     *
     * @return object
     */
    public function getAllAuthRole(): object
    {
        return AuthRole::where(['status' => AuthRole::STATUS_ENABLE])->select();
    }
}
